package tech.yunland.shop.domain.service;

import com.moyuer.bsf.domain.model.HqlArgs;
import com.moyuer.bsf.domain.service.LogService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tech.yunland.shop.domain.dao.FinanceBillDao;
import tech.yunland.shop.domain.model.FinanceBill;
import tech.yunland.shop.domain.model.Goods;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;

/**
 * 财务单
 *
 * @author 文卡<wkwenka@gmail.com>  on 17-2-22.
 */
@Service
public class FinanceBillService {

    @Autowired
    private FinanceBillDao financeBillDao;

    @Autowired
    private SNService snService;

    @Autowired
    private LogService logService;

    @Autowired
    private GoodsService goodsService;

    /**
     * 新增财务单
     *
     * @param financeBill
     */
    public void insertFinanceBill(FinanceBill financeBill) {
        String sn = snService.gen("financeBill", financeBill.getOrganId());
        financeBill.setSn(sn);

        String goodsId = financeBill.getGoods().getId();
        Goods goods = goodsService.get(goodsId);

        if (goods == null) {
            throw new RuntimeException("商品信息异常");
        }

        financeBill.setGoods(goods);
        BigDecimal price = goods.getPrice();
        BigDecimal quantity = financeBill.getQuantity();

        BigDecimal amount = price.multiply(quantity);

        financeBill.setState(Integer.valueOf(1));
        financeBill.setAmount(amount);

        financeBill.setActualPayment(amount);
        financeBill.setPayment(amount);

        financeBillDao.save(financeBill);

        logService.saveLog("新增财务单：[" + financeBill.getSn() + "],财务总额：" + new DecimalFormat("#.00").format(amount) + " 元", financeBill.getCreator());

    }

    /**
     * 删除财务单
     *
     * @param id
     */
    public void deleteFinanceBill(String id) {
        FinanceBill financeBill = financeBillDao.get(id);
        if (financeBill != null && financeBill.getState().intValue() != -1) {
            financeBill.setState(Integer.valueOf(-1));
        } else {
            throw new RuntimeException("此财务单已经删除");
        }
        logService.saveLog("财务单：[" + financeBill.getSn() + "] 已删除 ", financeBill.getCreator());
    }

    /**
     * 根据 id 获取财务单
     *
     * @param id
     * @return
     */
    public FinanceBill getFinanceBill(String id) {
        return financeBillDao.get(id);
    }

    public HqlArgs getHqlArgs(String organId, String param, List<Integer> states, Integer direction) {
        param = StringUtils.trimToEmpty(param);

        HashMap<String, Object> args = new HashMap<String, Object>();

        String hql = "FROM FinanceBill b WHERE b.organ.id = :organId";
        args.put("organId", organId);

        if (states != null) {
            if (states.size() == 1) {
                hql += " AND b.state = :states";
                args.put("states", states.get(0));
            } else {
                hql += " AND b.state in :states";
                args.put("states", states);
            }
        }

        if (direction != null) {
            hql += " AND b.direction = :direction";
            args.put("direction", direction);
        }

        if (StringUtils.isNotBlank(param)) {
            hql += " AND (b.sn LIKE :param OR b.goods.name LIKE :param)";
            args.put("param", param);
        }
        return new HqlArgs(hql, args);
    }

    /**
     * 查询所有财务单
     *
     * @param organId
     * @param param
     * @param states
     * @param direction
     * @param page
     * @param rows
     * @return
     */
    public List<FinanceBill> getFinanceBillList(String organId, String param, List<Integer> states, Integer direction, Integer page, Integer rows) {
        HqlArgs hqlArgs = getHqlArgs(organId, param, states, direction);
        String s = hqlArgs.getHql() + " ORDER BY b.createTime DESC";
        List<FinanceBill> billList = financeBillDao.findByNamedParam(s, page, rows, hqlArgs.getArgs());
        return billList;
    }

    /**
     * 查询所有单据数量
     *
     * @param organId
     * @param param
     * @param states
     * @param direction
     * @return
     */
    public Integer getListSize(String organId, String param, List<Integer> states, Integer direction) {
        HqlArgs hqlArgs = getHqlArgs(organId, param, states, direction);
         return (int)financeBillDao.getCount(hqlArgs.getHql(), hqlArgs.getArgs());
    }

    /**
     * 修改财务单
     *
     * @param financeBill
     */
    public void updateFinanceBill(FinanceBill financeBill) {
        String goodsId = financeBill.getGoods().getId();
        Goods goods = goodsService.get(goodsId);

        if (goods == null) {
            throw new RuntimeException("商品信息异常");
        }

        financeBill.setGoods(goods);
        BigDecimal price = goods.getPrice();
        BigDecimal quantity = financeBill.getQuantity();

        BigDecimal amount = price.multiply(quantity);

        financeBill.setState(Integer.valueOf(1));
        financeBill.setAmount(amount);

        Integer direction = financeBill.getDirection();
        financeBill.setPayment(amount);
        financeBill.setActualPayment(amount);

        financeBillDao.saveOrUpdate(financeBill);
        logService.saveLog("财务单：[" + financeBill.getSn() + "] 被修改", financeBill.getCreator());
    }
}
